<html>
<head><meta charset="utf-8"><title>Type arguments of method call · clippy · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/257328-clippy/index.html">clippy</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/257328-clippy/topic/Type.20arguments.20of.20method.20call.html">Type arguments of method call</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="234453764"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257328-clippy/topic/Type%20arguments%20of%20method%20call/near/234453764" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> boxdot <a href="https://rust-lang.github.io/zulip_archive/stream/257328-clippy/topic/Type.20arguments.20of.20method.20call.html#234453764">(Apr 14 2021 at 07:31)</a>:</h4>
<p>Is there a way to get the type arguments of a method call? Example: <code>std::collections::HashMap::&lt;String&gt;::iter() -&gt; [String]</code>. I managed to resolve the def id of the method by <code>cx.typeck_results().type_dependent_def_id(method.hir_id)</code>. But I am not sure where to go from there.</p>



<a name="234456651"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257328-clippy/topic/Type%20arguments%20of%20method%20call/near/234456651" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> flip1995 <a href="https://rust-lang.github.io/zulip_archive/stream/257328-clippy/topic/Type.20arguments.20of.20method.20call.html#234456651">(Apr 14 2021 at 07:54)</a>:</h4>
<p>Where did you get the <code>method</code> from? I would assume from matching an expression something like this:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">if</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">ExprKind</span>::<span class="n">MethodCall</span><span class="p">(</span><span class="n">method</span><span class="p">,</span><span class="w"> </span><span class="n">_</span><span class="p">,</span><span class="w"> </span><span class="n">args</span><span class="p">,</span><span class="w"> </span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">expr</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>In that case it is the array in the enum variant of <code>Call</code>/<code>MethodCall</code>. See also the documentation: <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/enum.ExprKind.html#variant.Call">https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/enum.ExprKind.html#variant.Call</a></p>
<p>Note that <code>HashMap::iter</code> has only one argument: <code>&amp;self</code>. In the <code>ExprKind</code> it is treated as just every other argument and the <code>args</code> array should have exactly one element.</p>



<a name="234456978"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257328-clippy/topic/Type%20arguments%20of%20method%20call/near/234456978" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> boxdot <a href="https://rust-lang.github.io/zulip_archive/stream/257328-clippy/topic/Type.20arguments.20of.20method.20call.html#234456978">(Apr 14 2021 at 07:57)</a>:</h4>
<p>Yes, I got <code>method</code> exactly like that. Do I understand correctly, that from <code>&amp;self</code> I would be able to get the generic param <code>String</code>?</p>



<a name="234466652"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257328-clippy/topic/Type%20arguments%20of%20method%20call/near/234466652" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> flip1995 <a href="https://rust-lang.github.io/zulip_archive/stream/257328-clippy/topic/Type.20arguments.20of.20method.20call.html#234466652">(Apr 14 2021 at 09:14)</a>:</h4>
<p>Depends on what you want to do. Since <code>&amp;self</code> is also an expression, you can use <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TypeckResults.html#method.expr_ty"><code>typeck_result.expr_ty(arg)</code></a>. And then destructure that type to get the the generics/substs of the <code>HashMap</code>. </p>
<p>Maybe it is also possible/easier to just call <code>expr_ty</code> on the <code>MethodCall</code> expression and just destructure the return type.</p>



<a name="234488162"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257328-clippy/topic/Type%20arguments%20of%20method%20call/near/234488162" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Michael Wright <a href="https://rust-lang.github.io/zulip_archive/stream/257328-clippy/topic/Type.20arguments.20of.20method.20call.html#234488162">(Apr 14 2021 at 12:21)</a>:</h4>
<p>I believe you can use <code>node_substs_opt</code> directly on <code>method.hir_id</code>.</p>
<p>Example:</p>
<div class="codehilite"><pre><span></span><code>    fn check_expr(&amp;mut self, cx: &amp;LateContext&lt;&#39;tcx&gt;, expr: &amp;&#39;tcx Expr&lt;&#39;_&gt;) {
        if_chain! {
            if let ExprKind::MethodCall(..) = &amp;expr.kind;
            if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
            if match_def_path(cx, def_id, &amp;[&quot;std&quot;, &quot;collections&quot;, &quot;hash&quot;, &quot;map&quot;, &quot;HashMap&quot;, &quot;iter&quot;]);
            if let Some(substs) = cx.typeck_results().node_substs_opt(expr.hir_id);
            if substs.len() &gt; 0;
            if is_type_diagnostic_item(cx, substs.type_at(0), sym::string_type);
            then {
                span_lint(
                    cx,
                    EXAMPLE,
                    expr.span,
                    &quot;HashMap&lt;String, _, _&gt;.iter() found&quot;,
                );
            }
        }
    }
</code></pre></div>
<p>The alternative is to examine the type of the receiver (first argument) but then you'll still have to examine substs and you'll have to wonder about whether to use <code>expr_ty</code> or <code>expr_ty_adjusted</code>. There are many examples of this in the clippy source.</p>



<a name="234633098"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257328-clippy/topic/Type%20arguments%20of%20method%20call/near/234633098" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> boxdot <a href="https://rust-lang.github.io/zulip_archive/stream/257328-clippy/topic/Type.20arguments.20of.20method.20call.html#234633098">(Apr 15 2021 at 07:57)</a>:</h4>
<p>Thank you both! This helped already a lot.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>